/*
 * @Author: i@rysa.cn
 * @Date: 2021-10-23 13:44:03
 * @LastEditTime: 2022-05-14 16:50:21
 * @LastEditors: i@rysa.cn
 * @Description:
 * @FilePath: \go-utils\strutil\string_encript.go
 */

package strutil

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
)

func PKCS7Padding(plaintext []byte, blockSize int) []byte {
	padding := blockSize - len(plaintext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(plaintext, padtext...)
}

func UnPKCS7Padding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}

/**
 * @name: AES加密 cbc
 * @description:
 * @param {*} origin 需要加密的字符串
 * @param {string} cip 密文
 * @return {*}
 */
func AesEncrypt(origin, cip string) (string, error) {
	origData := []byte(origin)
	key := []byte(cip)
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}
	//AES分组长度为128位，所以blockSize=16，单位字节
	blockSize := block.BlockSize()
	origData = PKCS7Padding(origData, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
	crypted := make([]byte, len(origData))
	blockMode.CryptBlocks(crypted, origData)
	return base64.StdEncoding.EncodeToString(crypted), nil
}

/**
 * @name: aes 解密
 * @description:
 * @param {*} encrypted  加密字符串
 * @param {string} cip 密文
 * @return {*}
 */
func AesDecrypt(encrypted, cip string) (string, error) {
	crypted, _ := base64.StdEncoding.DecodeString(encrypted)
	key := []byte(cip)
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}
	//AES分组长度为128位，所以blockSize=16，单位字节
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) //初始向量的长度必须等于块block的长度16字节
	origData := make([]byte, len(crypted))
	blockMode.CryptBlocks(origData, crypted)
	origData = UnPKCS7Padding(origData)
	return string(origData), nil
}
